package algorithms

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"

	"navigation-service/internal/models"
)

// AIService AI服务接口
type AIService interface {
	GenerateText(prompt string) (string, error)
	GenerateGrouping(features []models.URLFeature, config models.AIGroupingConfig) ([]models.AIGroup, error)
	OptimizeGroups(groups []models.AIGroup, userPrompt string) ([]models.AIGroup, error)
	AnalyzePatterns(features []models.URLFeature) (map[string]interface{}, error)
}

// OpenAIService OpenAI服务实现
type OpenAIService struct {
	apiKey         string
	baseURL        string
	model          string
	httpClient     *http.Client
	promptEngineer *PromptEngineer
}

// NewOpenAIService 创建OpenAI服务
func NewOpenAIService(apiKey, baseURL, model string) *OpenAIService {
	return &OpenAIService{
		apiKey:         apiKey,
		baseURL:        baseURL,
		model:          model,
		httpClient:     &http.Client{Timeout: 30 * time.Second},
		promptEngineer: NewPromptEngineer(),
	}
}

// OpenAIRequest OpenAI API请求结构
type OpenAIRequest struct {
	Model       string    `json:"model"`
	Messages    []Message `json:"messages"`
	Temperature float64   `json:"temperature"`
	MaxTokens   int       `json:"max_tokens"`
}

// Message 消息结构
type Message struct {
	Role    string `json:"role"`
	Content string `json:"content"`
}

// OpenAIResponse OpenAI API响应结构
type OpenAIResponse struct {
	ID      string `json:"id"`
	Object  string `json:"object"`
	Created int64  `json:"created"`
	Model   string `json:"model"`
	Choices []struct {
		Index   int `json:"index"`
		Message struct {
			Role    string `json:"role"`
			Content string `json:"content"`
		} `json:"message"`
		FinishReason string `json:"finish_reason"`
	} `json:"choices"`
	Usage struct {
		PromptTokens     int `json:"prompt_tokens"`
		CompletionTokens int `json:"completion_tokens"`
		TotalTokens      int `json:"total_tokens"`
	} `json:"usage"`
	Error *struct {
		Message string `json:"message"`
		Type    string `json:"type"`
		Code    string `json:"code"`
	} `json:"error,omitempty"`
}

// GenerateText 生成文本
func (s *OpenAIService) GenerateText(prompt string) (string, error) {
	request := OpenAIRequest{
		Model: s.model,
		Messages: []Message{
			{
				Role:    "user",
				Content: prompt,
			},
		},
		Temperature: 0.7,
		MaxTokens:   2000,
	}

	response, err := s.makeRequest(request)
	if err != nil {
		return "", err
	}

	if response.Error != nil {
		return "", fmt.Errorf("OpenAI API错误: %s", response.Error.Message)
	}

	if len(response.Choices) == 0 {
		return "", fmt.Errorf("OpenAI API返回空响应")
	}

	return response.Choices[0].Message.Content, nil
}

// GenerateGrouping 生成分组
func (s *OpenAIService) GenerateGrouping(features []models.URLFeature, config models.AIGroupingConfig) ([]models.AIGroup, error) {
	// 生成提示词
	prompt, err := s.promptEngineer.GenerateGroupingPrompt(features, config)
	if err != nil {
		return nil, fmt.Errorf("生成提示词失败: %v", err)
	}

	// 调用AI服务
	response, err := s.GenerateText(prompt)
	if err != nil {
		return nil, fmt.Errorf("AI服务调用失败: %v", err)
	}

	// 解析响应
	result, err := s.promptEngineer.ParseAIResponse(response, "grouping")
	if err != nil {
		return nil, fmt.Errorf("解析AI响应失败: %v", err)
	}

	groupingResult, ok := result.(struct {
		Groups []models.AIGroup `json:"groups"`
	})
	if !ok {
		return nil, fmt.Errorf("响应格式错误")
	}

	// 为分组添加ID和时间戳
	for i := range groupingResult.Groups {
		groupingResult.Groups[i].ID = fmt.Sprintf("ai_group_%d", i+1)
		groupingResult.Groups[i].CreatedAt = time.Now()
	}

	return groupingResult.Groups, nil
}

// OptimizeGroups 优化分组
func (s *OpenAIService) OptimizeGroups(groups []models.AIGroup, userPrompt string) ([]models.AIGroup, error) {
	// 生成优化提示词
	prompt, err := s.promptEngineer.GenerateOptimizationPrompt(groups, userPrompt)
	if err != nil {
		return nil, fmt.Errorf("生成优化提示词失败: %v", err)
	}

	// 调用AI服务
	response, err := s.GenerateText(prompt)
	if err != nil {
		return nil, fmt.Errorf("AI服务调用失败: %v", err)
	}

	// 解析响应
	result, err := s.promptEngineer.ParseAIResponse(response, "optimize_group")
	if err != nil {
		return nil, fmt.Errorf("解析AI响应失败: %v", err)
	}

	optimizeResult, ok := result.(struct {
		Groups  []models.AIGroup `json:"groups"`
		Changes []struct {
			Type        string `json:"type"`
			Description string `json:"description"`
		} `json:"changes"`
	})
	if !ok {
		return nil, fmt.Errorf("响应格式错误")
	}

	// 为分组添加ID和时间戳
	for i := range optimizeResult.Groups {
		optimizeResult.Groups[i].ID = fmt.Sprintf("ai_optimized_group_%d", i+1)
		optimizeResult.Groups[i].CreatedAt = time.Now()
	}

	return optimizeResult.Groups, nil
}

// AnalyzePatterns 分析模式
func (s *OpenAIService) AnalyzePatterns(features []models.URLFeature) (map[string]interface{}, error) {
	// 生成分析提示词
	prompt, err := s.promptEngineer.GenerateAnalysisPrompt(features)
	if err != nil {
		return nil, fmt.Errorf("生成分析提示词失败: %v", err)
	}

	// 调用AI服务
	response, err := s.GenerateText(prompt)
	if err != nil {
		return nil, fmt.Errorf("AI服务调用失败: %v", err)
	}

	// 解析响应
	result, err := s.promptEngineer.ParseAIResponse(response, "analyze_patterns")
	if err != nil {
		return nil, fmt.Errorf("解析AI响应失败: %v", err)
	}

	// 转换为map
	resultMap := make(map[string]interface{})
	resultBytes, err := json.Marshal(result)
	if err != nil {
		return nil, fmt.Errorf("序列化结果失败: %v", err)
	}

	err = json.Unmarshal(resultBytes, &resultMap)
	if err != nil {
		return nil, fmt.Errorf("反序列化结果失败: %v", err)
	}

	return resultMap, nil
}

// makeRequest 发送HTTP请求
func (s *OpenAIService) makeRequest(request OpenAIRequest) (*OpenAIResponse, error) {
	jsonData, err := json.Marshal(request)
	if err != nil {
		return nil, fmt.Errorf("序列化请求失败: %v", err)
	}

	req, err := http.NewRequest("POST", s.baseURL+"/v1/chat/completions", bytes.NewBuffer(jsonData))
	if err != nil {
		return nil, fmt.Errorf("创建请求失败: %v", err)
	}

	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "Bearer "+s.apiKey)

	resp, err := s.httpClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("发送请求失败: %v", err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("读取响应失败: %v", err)
	}

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("API请求失败，状态码: %d, 响应: %s", resp.StatusCode, string(body))
	}

	var response OpenAIResponse
	err = json.Unmarshal(body, &response)
	if err != nil {
		return nil, fmt.Errorf("解析响应失败: %v", err)
	}

	return &response, nil
}

// MockAIService 模拟AI服务（用于测试）
type MockAIService struct {
	promptEngineer *PromptEngineer
}

// NewMockAIService 创建模拟AI服务
func NewMockAIService() *MockAIService {
	return &MockAIService{
		promptEngineer: NewPromptEngineer(),
	}
}

// GenerateText 生成文本（模拟）
func (m *MockAIService) GenerateText(prompt string) (string, error) {
	// 模拟AI响应
	return `{
  "groups": [
    {
      "name": "技术开发",
      "description": "编程和技术相关网站",
      "icon": "💻",
      "color": "#3498db",
      "urls": ["https://github.com", "https://stackoverflow.com"],
      "confidence": 0.9
    },
    {
      "name": "新闻资讯",
      "description": "新闻和信息网站",
      "icon": "📰",
      "color": "#e74c3c",
      "urls": ["https://cnn.com", "https://bbc.com"],
      "confidence": 0.8
    }
  ]
}`, nil
}

// GenerateGrouping 生成分组（模拟）
func (m *MockAIService) GenerateGrouping(features []models.URLFeature, config models.AIGroupingConfig) ([]models.AIGroup, error) {
	// 使用模拟响应
	response, err := m.GenerateText("")
	if err != nil {
		return nil, err
	}

	// 解析响应
	result, err := m.promptEngineer.ParseAIResponse(response, "grouping")
	if err != nil {
		return nil, err
	}

	groupingResult, ok := result.(struct {
		Groups []models.AIGroup `json:"groups"`
	})
	if !ok {
		return nil, fmt.Errorf("响应格式错误")
	}

	// 为分组添加ID和时间戳
	for i := range groupingResult.Groups {
		groupingResult.Groups[i].ID = fmt.Sprintf("mock_group_%d", i+1)
		groupingResult.Groups[i].CreatedAt = time.Now()
	}

	return groupingResult.Groups, nil
}

// OptimizeGroups 优化分组（模拟）
func (m *MockAIService) OptimizeGroups(groups []models.AIGroup, userPrompt string) ([]models.AIGroup, error) {
	// 模拟优化：简单调整分组名称
	optimizedGroups := make([]models.AIGroup, len(groups))
	for i, group := range groups {
		optimizedGroups[i] = group
		optimizedGroups[i].Name = "优化后的" + group.Name
		optimizedGroups[i].ID = fmt.Sprintf("optimized_group_%d", i+1)
		optimizedGroups[i].CreatedAt = time.Now()
	}

	return optimizedGroups, nil
}

// AnalyzePatterns 分析模式（模拟）
func (m *MockAIService) AnalyzePatterns(features []models.URLFeature) (map[string]interface{}, error) {
	// 模拟分析结果
	result := map[string]interface{}{
		"interests": []string{"技术开发", "新闻资讯", "娱乐"},
		"timePreferences": map[string]interface{}{
			"peakHours":      []int{9, 14, 20},
			"weekdayPattern": "工作日主要访问工作相关网站",
			"weekendPattern": "周末主要访问娱乐相关网站",
		},
		"usageHabits": map[string]interface{}{
			"frequentDomains": []string{"github.com", "stackoverflow.com"},
			"browsingStyle":   "深度浏览",
		},
		"groupingSuggestions": []map[string]string{
			{
				"strategy": "按兴趣领域分组",
				"reason":   "用户有明显的兴趣偏好",
			},
		},
	}

	return result, nil
}

// AIServiceFactory AI服务工厂
type AIServiceFactory struct{}

// CreateService 创建AI服务
func (f *AIServiceFactory) CreateService(serviceType, apiKey, baseURL, model string) (AIService, error) {
	switch serviceType {
	case "openai":
		if apiKey == "" {
			return nil, fmt.Errorf("OpenAI API密钥不能为空")
		}
		if baseURL == "" {
			baseURL = "https://api.openai.com"
		}
		if model == "" {
			model = "gpt-3.5-turbo"
		}
		return NewOpenAIService(apiKey, baseURL, model), nil

	case "mock":
		return NewMockAIService(), nil

	default:
		return nil, fmt.Errorf("不支持的AI服务类型: %s", serviceType)
	}
}

// GetDefaultService 获取默认服务
func (f *AIServiceFactory) GetDefaultService() AIService {
	return NewMockAIService()
}
